package com.jeeos.project.ai.service.impl;

import java.io.*;
import java.util.*;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import com.jeeos.common.utils.DateUtils;
import com.jeeos.framework.config.JeeOsConfig;
import com.jeeos.project.system.domain.SysDictData;
import com.jeeos.project.system.service.ISysDictDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.jeeos.project.ai.mapper.AiReaderMapper;
import com.jeeos.project.ai.domain.AiReader;
import com.jeeos.project.ai.service.IAiReaderService;
import sun.misc.BASE64Decoder;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

/**
 * 电识别结果Service业务层处理
 *
 * @author jeeos
 * @date 2020-02-10
 */
@Service
public class AiReaderServiceImpl implements IAiReaderService {
    @Autowired
    private AiReaderMapper aiReaderMapper;

    @Autowired
    private ISysDictDataService dictDataService;

    private Map<String, List<SysDictData>> dictMap = new HashMap<>();


    /**
     * 查询电识别结果
     *
     * @param aiReaderId 电识别结果ID
     * @return 电识别结果
     */
    @Override

    public AiReader selectAiReaderById(String aiReaderId) {
        return aiReaderMapper.selectAiReaderById(aiReaderId);
    }

    /**
     * 查询电识别结果列表
     *
     * @param aiReader 电识别结果
     * @return 电识别结果
     */
    @Override
    public List<AiReader> selectAiReaderList(AiReader aiReader) {
        return aiReaderMapper.selectAiReaderList(aiReader);
    }

    /**
     * 新增电识别结果
     *
     * @param aiReader 电识别结果
     * @return 结果
     */
    @Override
    public int insertAiReader(AiReader aiReader) {
        aiReader.setAiReaderId(UUID.randomUUID().toString());
        aiReader.setCreateTime(DateUtils.getNowDate());
        return aiReaderMapper.insertAiReader(aiReader);
    }

    /**
     * 修改电识别结果
     *
     * @param aiReader 电识别结果
     * @return 结果
     */
    @Override
    public int updateAiReader(AiReader aiReader) {
        aiReader.setUpdateTime(DateUtils.getNowDate());
        return aiReaderMapper.updateAiReader(aiReader);
    }

    /**
     * 批量删除电识别结果
     *
     * @param aiReaderIds 需要删除的电识别结果ID
     * @return 结果
     */
    @Override
    public int deleteAiReaderByIds(String[] aiReaderIds) {
        return aiReaderMapper.deleteAiReaderByIds(aiReaderIds);
    }

    /**
     * 删除电识别结果信息
     *
     * @param aiReaderId 电识别结果ID
     * @return 结果
     */
    @Override
    public int deleteAiReaderById(String aiReaderId) {
        return aiReaderMapper.deleteAiReaderById(aiReaderId);
    }

    @Override
    public String zipAllImg(List<AiReader> list) throws IOException {
        List<String> imgNames = new ArrayList<>();
        for (AiReader aiReader : list) {
            String imgData = aiReader.getImg();
            String meterType = getDict("ai_meter_type", aiReader.getMeterType());
            String isRighr = getDict("ai_meter_reader_state", aiReader.getState());
            String rightNum = aiReader.getRightNumber() == null ? "无" : aiReader.getRightNumber();
            String num = aiReader.getNumber() == null ? "无" : aiReader.getNumber();

            String imgName = meterType + "_" + isRighr + "_" + rightNum + "_" + num + "_" + System.currentTimeMillis()+".jpg";
            if (GenerateImage(imgData, imgName)) {
                imgNames.add(imgName);
            }
            ;

        }
        String zipName = "识别结果.zip";
        compress(imgNames, zipName);

        return zipName;
    }


    public boolean GenerateImage(String imgData, String imgFilePath) throws IOException { // 对字节数组字符串进行Base64解码并生成图片
        if (imgData == null) // 图像数据为空
            return false;
        BASE64Decoder decoder = new BASE64Decoder();
        OutputStream out = null;
        try {
            out = new FileOutputStream(getAbsoluteFile(imgFilePath));
            // Base64解码
            byte[] b = decoder.decodeBuffer(imgData.replaceAll("data:image/jpeg;base64,",""));
            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {// 调整异常数据
                    b[i] += 256;
                }
            }
            out.write(b);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            out.flush();
            out.close();
            return true;
        }
    }

    /**
     * 获取下载路径
     *
     * @param filename 文件名称
     */
    public String getAbsoluteFile(String filename) {
        String downloadPath = JeeOsConfig.getDownloadPath() + filename;
        File desc = new File(downloadPath);
        if (!desc.getParentFile().exists()) {
            desc.getParentFile().mkdirs();
        }
        return downloadPath;
    }

    public String getDict(String type, String value) {
        List<SysDictData> sysDictData = new ArrayList<>();
        if(!dictMap.containsKey(type)){
            sysDictData = dictDataService.selectDictDataByType(type);
            dictMap.put(type,sysDictData);
        }else{
            sysDictData = dictMap.get(type);
        }

        String lable = "无值";
        for (SysDictData sysDictDatum : sysDictData) {
            String dictValue = sysDictDatum.getDictValue();
            if (value != null && value.equals(dictValue)) {
                lable = sysDictDatum.getDictLabel();
            }
        }
        return lable;
    }


    /**
     * 压缩文件
     *
     * @param imgPaths    压缩源文件路径
     * @param zipFileName 压缩目标文件路径
     */
    public void compress(List<String> imgPaths, String zipFileName) {


        byte[] buffer=new byte[512];
        ZipEntry zipEntry=null;
        int readLength=0;     //每次读取出来的长度

        try {
            // 对输出文件做CRC32校验
            CheckedOutputStream cos = new CheckedOutputStream(new FileOutputStream(
                    this.getAbsoluteFile(zipFileName)), new CRC32());
            ZipOutputStream zos = new ZipOutputStream(cos);

            for(String imgPath:imgPaths){

                    File file = new File(getAbsoluteFile(imgPath));
                    zipEntry=new ZipEntry(imgPath);  //
                    zipEntry.setSize(file.length());
                    zipEntry.setTime(file.lastModified());
                    zos.putNextEntry(zipEntry);

                    InputStream is=new BufferedInputStream(new FileInputStream(file));

                    while ((readLength=is.read(buffer,0,512))!=-1){
                        zos.write(buffer,0,readLength);
                    }
                    is.close();
                    System.out.println("file compress:"+file.getCanonicalPath());

            }
            zos.close();  //最后得关闭流，不然压缩最后一个文件会出错
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

